package com.genius.workflow.util;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Random;

import org.apache.commons.fileupload.FileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.genius.workflow.exception.ImgException;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
public class OSSClientContorller {
	private  Logger log = LoggerFactory.getLogger(OSSClientContorller.class);
	  // endpoint以杭州为例，其它region请按实际情况填写
	  private String endpoint = "oss-cn-zhangjiakou.aliyuncs.com";
	  // accessKey
	  private String accessKeyId = "LTAI67zMng4CyPb0";
	  private String accessKeySecret = "yNvfx1QTmy6UmN9AVaDxqzvFSlQ3AT";
	  //空间
	  private String bucketName = "unite-platform";
	  //文件存储目录
	  private String filedir = "";
	 
	  private OSSClient ossClient;
	 
	  public OSSClientContorller() {
	    ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
	  }
	 
	  /**
	   * 初始化
	   */
	  public void init() {
	    ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
	  }
	 
	  /**
	   * 销毁
	   */
	  public void destory() {
	    ossClient.shutdown();
	  }
	 
	  /**
	   * 上传图片
	   *
	   * @param url
	 * @throws IOException 
	   */
	  public String uploadImg2Oss(String url){
		
	    System.out.println(url);
	    String substring = url.substring(url.lastIndexOf(".")).toLowerCase();
	    Random random = new Random();
	    String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
	    try {
    	String[] split = url.split("/");
	      this.uploadUrlOSS(url, name);
	      return name;
	    } catch (Exception e) {
	    	e.printStackTrace();
	      throw new ImgException("图片上传失败");
	    }
	  }
	 
	  public JSONObject uploadImg2Oss( MultipartFile file) {
	    if (file.getSize() > 1024 * 1024) {
//	      throw new ImgException("上传图片大小不能超过1M！");
			JSONObject result = new JSONObject();
			result.put("msg", "上传图片大小不能超过1M！");
			result.put("flag", "1");
			return result;
	    }
	    String originalFilename = file.getOriginalFilename();
	    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
	    Random random = new Random();
	    String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
	    JSONObject result = new JSONObject();
	    try {
	      InputStream inputStream = file.getInputStream();
	      this.uploadFile2OSS(inputStream, name);
	      System.out.println("name-->>"+name);
	      String src = getImgUrl(name);
	      System.out.println("url-->>"+src);
	      result.put("src", src);
	      result.put("msg", "图片上传成功");
	      result.put("flag", "0");
//	      return result;
	    } catch (Exception e) {
	    	result.put("msg", "图片上传失败");
			result.put("flag", "1");
	    	e.printStackTrace();
//	      throw new ImgException("图片上传失败");
	    }
		return result;
	  }
	  public JSONObject uploadFileOss( MultipartFile file) {
		  JSONObject result = new JSONObject();
		    String originalFilename = file.getOriginalFilename();
		    String nameStr = originalFilename.substring(0,originalFilename.lastIndexOf(".")).toLowerCase();
		    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
		    String name = nameStr+"_" + System.currentTimeMillis() + substring;
//		    System.out.println(name);
		    try {
		      InputStream inputStream = file.getInputStream();
		      this.uploadFile2OSS(inputStream, name);
		      System.out.println("name-->>"+name);
		      String src = getImgUrl(name);
		      System.out.println("url-->>"+src);
		      
		      result.put("src", src);
		      result.put("msg", "文件上传成功");
		      return result;
		    } catch (Exception e) {
		    	result.put("msg", "文件上传失败");
		    	e.printStackTrace();
//		      throw new ImgException("文件上传失败");
		    }
			return result;
		  }
	  public String uploadImg2Oss(FileItem file) {
		    if (file.getSize() > 1024 * 1024) {
		      throw new ImgException("上传图片大小不能超过1M！");
		    }
		    String originalFilename = file.getName();
		    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
		    Random random = new Random();
		    String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
		    try {
		      InputStream inputStream = file.getInputStream();
		      this.uploadFile2OSS(inputStream, name);
		      return name;
		    } catch (Exception e) {
		      throw new ImgException("图片上传失败");
		    }
		  }
	  
	  public String uploadVideoOss(FileItem file) {
		 
		    String originalFilename = file.getName();
		    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
		    Random random = new Random();
		    String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
		    try {
		      InputStream inputStream = file.getInputStream();
		      this.uploadVideoOSS(inputStream, name);
		      return name;
		    } catch (Exception e) {
		      throw new ImgException("视频上传失败");
		    }
		  }
	  public JSONObject uploadVideoOss(MultipartFile file) {
		  JSONObject result = new JSONObject();
		  String originalFilename = file.getOriginalFilename();
		    String nameStr = originalFilename.substring(0,originalFilename.lastIndexOf(".")).toLowerCase();
		    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
		    String name = nameStr+"_" + System.currentTimeMillis() + substring;
		    try {
		      InputStream inputStream = file.getInputStream();
		      this.uploadVideoOSS(inputStream, name);
		      String src = getImgUrl(name);
		      System.out.println("url-->>"+src);
		      
		      result.put("src", src);
		      result.put("msg", "视频上传成功");
		      return result;
		    } catch (Exception e) {
		    	result.put("msg", "视频上传失败");
		    	e.printStackTrace();
//		      throw new ImgException("视频上传失败");
		    }
			return result;
		  }
	  /**
	   * 获得图片路径
	   *
	   * @param fileUrl
	   * @return
	   */
	  public String getImgUrl(String fileUrl) {
	    if (fileUrl != null && !fileUrl.trim().equals("")) {
	      String[] split = fileUrl.split("/");
	      return this.getUrl(this.filedir + split[split.length - 1]);
	    }
	    return null;
	  }
	 
	  /**
	   * 上传到OSS服务器  如果同名文件会覆盖服务器上的
	   *
	   * @param instream 文件流
	   * @param fileName 文件名称 包括后缀名
	   * @return 出错返回"" ,唯一MD5数字签名
	   */
	  public String uploadFile2OSS(InputStream instream, String fileName) {
			/*
			 * System.out.println("instream>>>>>>"+instream);
			 * System.out.println("fileName>>>>>>"+fileName);
			 * System.out.println("bucketName>>>>>>"+bucketName);
			 * System.out.println("filedir>>>>>>"+filedir);
			 */
	    String ret = "";
	    try {
	      //创建上传Object的Metadata 
	      ObjectMetadata objectMetadata = new ObjectMetadata();
	      objectMetadata.setContentLength(instream.available());
	      objectMetadata.setCacheControl("no-cache");
	      objectMetadata.setHeader("Pragma", "no-cache");
	     // objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
	      objectMetadata.setContentDisposition("inline;filename=" + fileName);
	   //   System.out.println("ObjectMetadata>>>>>>"+objectMetadata);
	      //上传文件
	      PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);
	      
	      ret = putResult.getETag();
	    } catch (IOException e) {
	      log.error(e.getMessage(), e);
	    } finally {
	      try {
	        if (instream != null) {
	          instream.close();
	        }
	      } catch (IOException e) {
	        e.printStackTrace();
	      }
	    }
	    return ret;
	  }
	 
	  /**
	   * 上传到OSS服务器  如果同名文件会覆盖服务器上的
	   *
	   * @param instream 文件流
	   * @param fileName 文件名称 包括后缀名
	   * @return 出错返回"" ,唯一MD5数字签名
	   */
	  public String uploadVideoOSS(InputStream instream, String fileName) {
	    String ret = "";
	    try {
	    	String a = "video/mp4";
	      //创建上传Object的Metadata 
	      ObjectMetadata objectMetadata = new ObjectMetadata();
	      objectMetadata.setContentType("video/mp4");
//	      objectMetadata.setContentLength(instream.available());
//	      objectMetadata.setCacheControl("no-cache");
//	      objectMetadata.setHeader("Pragma", "no-cache");
//	      objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
//	      objectMetadata.setContentDisposition("inline;filename=" + fileName);
	      //上传文件
	      PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);
	      
	      ret = putResult.getETag();
	    } catch (Exception e) {
	      log.error(e.getMessage(), e);
	    } finally {
	      try {
	        if (instream != null) {
	          instream.close();
	        }
	      } catch (IOException e) {
	        e.printStackTrace();
	      }
	    }
	    return ret;
	  }
	  
	  /**
	   * 上传到OSS服务器  如果同名文件会覆盖服务器上的
	   *
	   * @param instream 文件流
	   * @param fileName 文件名称 包括后缀名
	   * @return 出错返回"" ,唯一MD5数字签名
	   */
	  public String uploadFile2OSS(File file, String fileName) {
	    String ret = "";
	    try {
	      //创建上传Object的Metadata 
	      ObjectMetadata objectMetadata = new ObjectMetadata();
	      objectMetadata.setCacheControl("no-cache");
	      objectMetadata.setHeader("Pragma", "no-cache");
	      objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
	      objectMetadata.setContentDisposition("inline;filename=" + fileName);
	      //上传文件
	      PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, file, objectMetadata);
	      
	      ret = putResult.getETag();
	    } catch (Exception e) {
	    	e.printStackTrace();
	      log.error(e.getMessage(), e);
	    } finally {
	      
	    }
	    return ret;
	  }
	  /**
	   * 上传到OSS服务器  如果同名文件会覆盖服务器上的
	   *
	   * @param url 图片网络地址
	   * @param fileName 文件名称 包括后缀名
	   * @return 出错返回"" ,唯一MD5数字签名
	   */
	  public String uploadUrlOSS(String url, String fileName) {
	    String ret = "";
	    InputStream instream = null;
	    try {
	       //上传文件
	      instream = new URL(url).openStream();
	      PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream);
//	      PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);
	      
	      ret = putResult.getETag();
	    } catch (IOException e) {
	      log.error(e.getMessage(), e);
	    } finally {
	      try {
	        if (instream != null) {
	          instream.close();
	        }
	      } catch (IOException e) {
	        e.printStackTrace();
	      }
	    }
	    return ret;
	  }
	  /**
	   * Description: 判断OSS服务文件上传时文件的contentType
	   *
	   * @param FilenameExtension 文件后缀
	   * @return String
	   */
	  public static String getcontentType(String FilenameExtension) {
	    if (FilenameExtension.equalsIgnoreCase(".bmp")) {
	      return "image/bmp";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".gif")) {
	      return "image/gif";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
	        FilenameExtension.equalsIgnoreCase(".jpg") ||
	        FilenameExtension.equalsIgnoreCase(".png")) {
	      return "image/jpeg";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".html")) {
	      return "text/html";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".txt")) {
	      return "text/plain";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".vsd")) {
	      return "application/vnd.visio";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".pptx") ||
	        FilenameExtension.equalsIgnoreCase(".ppt")) {
	      return "application/vnd.ms-powerpoint";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".docx") ||
	        FilenameExtension.equalsIgnoreCase(".doc")) {
	      return "application/msword";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".xml")) {
	      return "text/xml";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".xlsx") ||
	        FilenameExtension.equalsIgnoreCase(".xls")) {
	      return "application/vnd.ms-excel";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".pdf")) {
	      return "chemical/x-pdb";
	    }
	    return "image/jpeg";
	  }
	 
	  /**
	   * 获得url链接
	   *
	   * @param key
	   * @return
	   */
	  public String getUrl(String key) {
	    // 设置URL过期时间为10年  3600l* 1000*24*365*10
	    Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);
	    // 生成URL
	    URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
	    if (url != null) {
	      return url.toString();
	    }
	    return null;
	  }
	  /**
	   * 删除oss文件
	   *
	   * @param key
	   * @return
	   */
	  public void deleteImgOss(String key) {
		boolean found = ossClient.doesObjectExist(bucketName, key);
		if(found){
			 ossClient.deleteObject(bucketName, key);
		}else{
			 throw new ImgException("已经删除");
		}
	   
//	    ossClient.shutdown();
	    
	  }
	  /**
	   * 获取下载链接
	 * @throws UnsupportedEncodingException 
	   */
	  public String getDownUrl(String key) throws UnsupportedEncodingException{
		  //disposition 入参（"attachment" 及 "inline" ）来选择性生成预览或者下载的链接了
		  Date expiration = new Date(new Date().getTime() + 1800 * 1000);
		  GeneratePresignedUrlRequest generatePresignedUrlRequest;
		  String attachment = "?response-content-disposition=attachment";
		  String attachmentEncoder = encoder(attachment);

		  key = key + attachment;

		  generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
		  generatePresignedUrlRequest.setExpiration(expiration);
		  String url = ossClient.generatePresignedUrl(generatePresignedUrlRequest).toString().replace(attachmentEncoder + "?", attachment + "&");
		  
		return url;

		     
	  }
	  private String encoder(String s) throws UnsupportedEncodingException {
          String encoder = URLEncoder.encode(s, "UTF-8");
          encoder = encoder.replaceAll("\\+", "%20");
          encoder = encoder.replaceAll("\\*", "%2A");
          return encoder;
      }
	  
}
